From 62ce6d0181cfbd0f84005fb5e06970124fc964c3 Mon Sep 17 00:00:00 2001 From: robertl Date: Sun, 5 Nov 2006 22:48:42 +0000 Subject: [PATCH] Memory leaks and stability fixes in KML realtime writer. Allow position reader (Garmin, NMEA) to propogate error up to caller. --- gpsbabel/defs.h | 6 ++++- gpsbabel/garmin.c | 12 +++++++-- gpsbabel/kml.c | 36 ++++++++++++++------------ gpsbabel/main.c | 21 ++++++++++++--- gpsbabel/nmea.c | 9 ++++--- gpsbabel/reference/earth-expertgps.kml | 2 +- gpsbabel/reference/earth-gc.kml | 2 +- 7 files changed, 58 insertions(+), 30 deletions(-) diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 4236e79aa..3c2d5ad93 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -399,13 +399,17 @@ typedef struct { double min_lon; } bounds; +typedef struct { + int request_terminate; +} posn_status; + typedef void (*ff_init) (char const *); typedef void (*ff_deinit) (void); typedef void (*ff_read) (void); typedef void (*ff_write) (void); typedef void (*ff_exit) (void); typedef void (*ff_writeposn) (waypoint *); -typedef waypoint * (*ff_readposn) (void); +typedef waypoint * (*ff_readposn) (posn_status *); #ifndef DEBUG_MEM char * get_option(const char *iarglist, const char *argname); diff --git a/gpsbabel/garmin.c b/gpsbabel/garmin.c index 3f74b8088..c696357b0 100644 --- a/gpsbabel/garmin.c +++ b/gpsbabel/garmin.c @@ -469,7 +469,7 @@ pvt_init(const char *fname) } static waypoint * -pvt_read(void) +pvt_read(posn_status *posn_status) { waypoint *wpt = waypt_new(); GPS_PPvt_Data pvt = GPS_Pvt_New(); @@ -477,10 +477,18 @@ pvt_read(void) if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { pvt2wpt(pvt, wpt); wpt->shortname = xstrdup("Position"); + + if (gps_errno && posn_status) { + posn_status->request_terminate = 1; + } return wpt; } + /* + * If the caller has not given us a better way to return the + * error, do it now. + */ if (gps_errno) { fatal(MYNAME ": Fatal error reading position.\n"); } @@ -825,7 +833,7 @@ ff_vecs_t garmin_vecs = { NULL, garmin_args, CET_CHARSET_ASCII, 0, - { pvt_init, pvt_read, NULL, NULL, NULL, NULL } + { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } }; static const char *d103_icons[16] = { diff --git a/gpsbabel/kml.c b/gpsbabel/kml.c index a6aef2628..aad687678 100644 --- a/gpsbabel/kml.c +++ b/gpsbabel/kml.c @@ -40,7 +40,6 @@ static int export_points; static int floating; static int extrude; static int trackdata; -static int posn_track_points; static int max_position_points; static int indent_level; @@ -807,7 +806,7 @@ void kml_write(void) kml_write_xml(0,"\n"); kml_write_xml(1,"\n"); - kml_write_xml(1,"\n"); + kml_write_xml(1,"\n"); now = current_time(); strftime(import_time, sizeof(import_time), "%c", localtime(&now)); @@ -882,12 +881,17 @@ kml_get_posn_icon(int freshness) } +static route_head *posn_trk_head = NULL; + static void kml_wr_position(waypoint *wpt) { - static route_head *trk_head = NULL; static time_t last_valid_fix; - waypoint *t = waypt_dupe(wpt); + + if (!posn_trk_head) { + posn_trk_head = route_head_alloc(); + track_add_head(posn_trk_head); + } if (last_valid_fix == 0) last_valid_fix = current_time(); @@ -913,25 +917,23 @@ kml_wr_position(waypoint *wpt) last_valid_fix = wpt->creation_time; } - wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); - if (!trk_head) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - if (max_position_points && (posn_track_points >= max_position_points)) { - waypoint *tonuke = (waypoint *) QUEUE_FIRST(&trk_head->waypoint_list); - dequeue(&tonuke->Q); - waypt_free(tonuke); - } - - track_add_wpt(trk_head, t); - posn_track_points++; + track_add_wpt(posn_trk_head, waypt_dupe(wpt)); waypt_add(wpt); kml_write(); waypt_del(wpt); + + /* + * If we are keeping only a recent subset of the trail, trim the + * head here. + */ + while (max_position_points && + (posn_trk_head->rte_waypt_ct >= max_position_points)) { + waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); + track_del_wpt(posn_trk_head, tonuke); + } } ff_vecs_t kml_vecs = { diff --git a/gpsbabel/main.c b/gpsbabel/main.c index d06c0862c..06e49d161 100644 --- a/gpsbabel/main.c +++ b/gpsbabel/main.c @@ -541,7 +541,6 @@ main(int argc, char *argv[]) * in our most recent vecs. */ if (global_opts.masked_objective & POSNDATAMASK) { - waypoint *wpt = waypt_new(); if (!ivecs->position_ops.rd_position) { fatal("Realtime tracking (-T) is not suppored by this input type.\n"); @@ -565,7 +564,15 @@ main(int argc, char *argv[]) } while (1) { - wpt = ivecs->position_ops.rd_position(); + posn_status status; + status.request_terminate = 0; + waypoint *wpt = ivecs->position_ops.rd_position(&status); + if (status.request_terminate) { + if (wpt) { + waypt_free(wpt); + } + break; + } if (wpt) { if (ovecs) { ovecs->position_ops.wr_init(ofname); @@ -575,11 +582,17 @@ main(int argc, char *argv[]) /* Just print to screen */ waypt_disp(wpt); } + waypt_free(wpt); } } -// waypt_del(wpt); + if (ivecs->position_ops.rd_deinit) { + ivecs->position_ops.rd_deinit(); + } + if (ivecs->position_ops.wr_deinit) { + ivecs->position_ops.wr_deinit(); + } } - + if (!did_something) fatal ("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); diff --git a/gpsbabel/nmea.c b/gpsbabel/nmea.c index b078ba39b..7d946e57a 100644 --- a/gpsbabel/nmea.c +++ b/gpsbabel/nmea.c @@ -179,7 +179,7 @@ static int getposn; static time_t last_time = -1; static double last_read_time; /* Last timestamp of GGA or PRMC */ -static waypoint * nmea_rd_posn(void); +static waypoint * nmea_rd_posn(posn_status *); static void nmea_rd_posn_init(const char *fname); arglist_t nmea_args[] = { @@ -226,8 +226,9 @@ nmea_rd_init(const char *fname) */ if (getposn) { waypoint *wpt; + posn_status st; nmea_rd_posn_init(fname); - wpt = nmea_rd_posn(); + wpt = nmea_rd_posn(&st); if (!wpt) { return; } @@ -817,7 +818,7 @@ nmea_rd_posn_init(const char *fname) read_mode = rm_serial; gbser_set_speed(gbser_handle, 4800); } else { - fatal(MYNAME ": Could not open %s.\n", fname); + fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); } if (opt_baud) { @@ -829,7 +830,7 @@ nmea_rd_posn_init(const char *fname) } static waypoint * -nmea_rd_posn(void) +nmea_rd_posn(posn_status *posn_status) { char ibuf[1024]; static double lt = -1; diff --git a/gpsbabel/reference/earth-expertgps.kml b/gpsbabel/reference/earth-expertgps.kml index c434cb89c..3d97dacac 100644 --- a/gpsbabel/reference/earth-expertgps.kml +++ b/gpsbabel/reference/earth-expertgps.kml @@ -1,6 +1,6 @@ - + GPS device